<template>
  <div class="permission-container">
    <div class="filter-container">
      <el-form :inline="true" :model="filterForm">
        <el-form-item label="权限名称">
          <el-input
            v-model="filterForm.permissionName"
            placeholder="请输入权限名称"
            clearable
            prefix-icon="Search"
          />
        </el-form-item>
        <el-form-item label="权限类型">
          <el-select
            v-model="filterForm.permissionType"
            placeholder="请选择权限类型"
            clearable
            style="width: 150px"
          >
            <el-option label="菜单" :value="1" />
            <el-option label="按钮" :value="2" />
            <el-option label="API" :value="3" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态">
          <el-select
            v-model="filterForm.status"
            placeholder="请选择状态"
            clearable
            style="width: 150px"
          >
            <el-option label="启用" :value="1" />
            <el-option label="禁用" :value="0" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            v-permission="'permission:query'"
            @click="handleFilter"
          >
            <el-icon><Search /></el-icon>
            查询
          </el-button>
          <el-button
            v-permission="'permission:add'"
            type="success"
            @click="handleAdd(0)"
          >
            <el-icon><Plus /></el-icon>
            新增权限
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 权限树 -->
    <el-card shadow="hover" class="permission-tree-card">
      <template #header>
        <div class="tree-header">
          <div class="header-left">
            <h3>权限管理</h3>
            <el-tag
              type="info"
              effect="plain"
              size="small"
              class="permission-count"
            >
              {{ permissionTree.length }} 项权限
            </el-tag>
          </div>
          <div class="header-right">
            <div class="tree-legend">
              <div class="legend-item">
                <el-tag size="small" type="success" effect="light">菜单</el-tag>
              </div>
              <div class="legend-item">
                <el-tag size="small" type="warning" effect="light">按钮</el-tag>
              </div>
              <div class="legend-item">
                <el-tag size="small" type="info" effect="light">API</el-tag>
              </div>
            </div>
            <el-tooltip content="点击刷新权限树" placement="top">
              <el-button
                type="primary"
                :icon="Refresh"
                circle
                plain
                size="small"
                @click="fetchPermissionTree"
              ></el-button>
            </el-tooltip>
          </div>
        </div>
      </template>

      <!-- 权限树表头 -->
      <div class="tree-table-header">
        <div class="table-header-item">ID</div>
        <div class="table-header-item table-header-name">权限名称</div>
        <div class="table-header-item table-header-type">类型</div>
        <div class="table-header-item table-header-code">权限编码</div>
        <div class="table-header-item table-header-action">操作</div>
      </div>

      <el-tree
        ref="permissionTreeRef"
        :data="permissionTree"
        :props="defaultProps"
        node-key="id"
        default-expand-all
        highlight-current
        :expand-on-click-node="false"
      >
        <template #default="{ data }">
          <div class="custom-tree-node">
            <div class="node-id">{{ data.id }}</div>
            <div class="node-label">
              <el-icon v-if="data.icon"><component :is="data.icon" /></el-icon>
              <el-icon v-else>
                <component :is="getDefaultIcon(data.permissionType)" />
              </el-icon>
              <span>{{ data.permissionName }}</span>
            </div>
            <div class="node-type">
              <el-tag
                size="small"
                :type="getTagType(data.permissionType)"
                effect="light"
              >
                {{ getPermissionTypeName(data.permissionType) }}
              </el-tag>
            </div>
            <div class="node-code">
              <el-tag
                size="small"
                type="info"
                effect="plain"
                v-if="data.permissionCode"
              >
                {{ data.permissionCode }}
              </el-tag>
            </div>
            <div class="node-actions">
              <el-button
                v-permission="'permission:add'"
                class="action-button"
                type="primary"
                plain
                size="small"
                @click.stop="handleAdd(data.id)"
              >
                <el-icon><Plus /></el-icon>
                <span>添加子权限</span>
              </el-button>
              <el-button
                v-permission="'permission:edit'"
                class="action-button"
                type="primary"
                plain
                size="small"
                @click.stop="handleEdit(data)"
              >
                <el-icon><Edit /></el-icon>
                <span>编辑</span>
              </el-button>
              <el-button
                v-permission="'permission:delete'"
                class="action-button"
                type="danger"
                plain
                size="small"
                @click.stop="handleDelete(data)"
              >
                <el-icon><Delete /></el-icon>
                <span>删除</span>
              </el-button>
            </div>
          </div>
        </template>
      </el-tree>

      <!-- 树为空时的占位内容 -->
      <el-empty v-if="permissionTree.length === 0" description="暂无权限数据">
        <el-button type="primary" @click="handleAdd(0)">添加权限</el-button>
      </el-empty>
    </el-card>

    <!-- 权限表单对话框 -->
    <el-dialog
      :title="dialogStatus === 'create' ? '新增权限' : '编辑权限'"
      v-model="dialogVisible"
      width="500px"
      @close="resetForm"
      :close-on-click-modal="false"
    >
      <el-form
        ref="permissionFormRef"
        :model="permissionForm"
        :rules="permissionRules"
        label-width="100px"
      >
        <el-form-item label="权限类型" prop="permissionType">
          <el-select
            v-model="permissionForm.permissionType"
            placeholder="请选择权限类型"
          >
            <el-option label="菜单" :value="1" />
            <el-option label="按钮" :value="2" />
            <el-option label="API" :value="3" />
          </el-select>
        </el-form-item>
        <el-form-item label="权限名称" prop="permissionName">
          <el-input
            v-model="permissionForm.permissionName"
            placeholder="请输入权限名称"
          />
        </el-form-item>
        <el-form-item label="权限编码" prop="permissionCode">
          <el-input
            v-model="permissionForm.permissionCode"
            placeholder="请输入权限编码"
          />
          <div class="form-tip">示例: user:list, 格式为 模块:操作[:资源]</div>
        </el-form-item>
        <!-- 菜单特有字段 -->
        <template v-if="permissionForm.permissionType === 1">
          <el-form-item label="路由路径" prop="path">
            <el-input
              v-model="permissionForm.path"
              placeholder="请输入路由路径"
            />
            <div class="form-tip">示例: /home/user/list</div>
          </el-form-item>
          <el-form-item label="组件路径" prop="component">
            <el-input
              v-model="permissionForm.component"
              placeholder="请输入组件路径"
            />
            <div class="form-tip">示例: @/views/user/UserManage.vue</div>
          </el-form-item>
          <el-form-item label="图标" prop="icon">
            <el-popover placement="bottom" :width="400" trigger="click">
              <template #reference>
                <el-input
                  v-model="permissionForm.icon"
                  placeholder="请选择图标"
                >
                  <template #append>
                    <el-icon v-if="permissionForm.icon">
                      <component :is="permissionForm.icon" />
                    </el-icon>
                  </template>
                </el-input>
              </template>
              <div class="icon-selector">
                <div
                  v-for="icon in iconList"
                  :key="icon"
                  class="icon-item"
                  @click="permissionForm.icon = icon"
                >
                  <el-icon>
                    <component :is="icon" />
                  </el-icon>
                  <span>{{ icon }}</span>
                </div>
              </div>
            </el-popover>
          </el-form-item>
        </template>
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="permissionForm.sort" :min="0" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="permissionForm.status">
            <el-radio :label="1">启用</el-radio>
            <el-radio :label="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button
          type="primary"
          v-permission="'permission:add'"
          v-if="dialogStatus === 'create'"
          @click="submitForm"
          >确定</el-button
        >
        <el-button
          type="primary"
          v-permission="'permission:edit'"
          v-else
          @click="submitForm"
          >确定</el-button
        >
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import { Refresh, Plus, Edit, Delete, Search } from '@element-plus/icons-vue'
import {
  getPermissionTree,
  addPermission,
  updatePermission,
  deletePermission
} from '@/api/permission'

// 图标列表
const iconList = computed(() => {
  return Object.keys(ElementPlusIconsVue)
})

// 过滤表单
const filterForm = reactive({
  permissionName: '',
  permissionType: null,
  status: null
})

// 权限树数据
const permissionTreeRef = ref(null)
const permissionTree = ref([])
const defaultProps = {
  children: 'children',
  label: 'permissionName'
}

// 对话框状态
const dialogVisible = ref(false)
const dialogStatus = ref('create')
const permissionFormRef = ref(null)
const permissionForm = reactive({
  id: null,
  permissionName: '',
  permissionCode: '',
  permissionType: 1,
  parentId: 0,
  path: '',
  component: '',
  icon: '',
  sort: 0,
  status: 1
})

// 表单验证规则
const permissionRules = {
  permissionName: [
    { required: true, message: '请输入权限名称', trigger: 'blur' }
  ],
  permissionCode: [
    { required: true, message: '请输入权限编码', trigger: 'blur' }
  ],
  permissionType: [
    { required: true, message: '请选择权限类型', trigger: 'change' }
  ],
  path: [{ required: true, message: '请输入路由路径', trigger: 'blur' }],
  component: [{ required: true, message: '请输入组件路径', trigger: 'blur' }],
  sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
  status: [{ required: true, message: '请选择状态', trigger: 'change' }]
}

// 获取权限类型名称
const getPermissionTypeName = (type) => {
  switch (type) {
    case 1:
      return '菜单'
    case 2:
      return '按钮'
    case 3:
      return 'API'
    default:
      return '未知'
  }
}

// 获取标签类型
const getTagType = (type) => {
  switch (type) {
    case 1:
      return 'success'
    case 2:
      return 'warning'
    case 3:
      return 'info'
    default:
      return ''
  }
}

// 获取默认图标
const getDefaultIcon = (type) => {
  switch (type) {
    case 1:
      return 'Document' // 菜单
    case 2:
      return 'Setting' // 按钮
    case 3:
      return 'Document' // API
    default:
      return 'Document'
  }
}

// 查询权限树
const fetchPermissionTree = async () => {
  try {
    const res = await getPermissionTree()
    if (res.data.code === 1) {
      permissionTree.value = res.data.data || []
    } else {
      ElMessage.error(res.data.msg || '获取权限树失败')
    }
  } catch (error) {
    console.error('获取权限树失败', error)
    ElMessage.error('获取权限树失败')
  }
}

// 过滤权限树
const handleFilter = () => {
  fetchPermissionTree().then(() => {
    // 如果有过滤条件，前端过滤
    if (
      filterForm.permissionType ||
      filterForm.permissionName ||
      filterForm.status !== null
    ) {
      const filterNode = (data) => {
        // 过滤权限类型
        const typeMatch =
          !filterForm.permissionType ||
          data.permissionType === filterForm.permissionType

        // 过滤权限名称
        const nameMatch =
          !filterForm.permissionName ||
          data.permissionName
            .toLowerCase()
            .includes(filterForm.permissionName.toLowerCase())

        // 过滤状态
        const statusMatch =
          filterForm.status === null || data.status === filterForm.status

        // 当前节点是否匹配
        const currentNodeMatch = typeMatch && nameMatch && statusMatch

        // 递归检查子节点
        if (data.children && data.children.length) {
          data.children = data.children.filter(filterNode)
          return currentNodeMatch || data.children.length > 0
        }

        return currentNodeMatch
      }

      permissionTree.value = permissionTree.value.filter(filterNode)
    }
  })
}

// 新增权限
const handleAdd = (parentId) => {
  resetForm()
  dialogStatus.value = 'create'
  permissionForm.parentId = parentId
  dialogVisible.value = true
}

// 编辑权限
const handleEdit = (data) => {
  resetForm()
  dialogStatus.value = 'update'
  Object.assign(permissionForm, data)
  dialogVisible.value = true
}

// 删除权限
const handleDelete = (data) => {
  ElMessageBox.confirm(`确认删除权限 ${data.permissionName} 吗？`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      try {
        const res = await deletePermission(data.id)
        if (res.data.code === 1) {
          ElMessage.success('删除成功')
          fetchPermissionTree()
        } else {
          ElMessage.error(res.data.msg || '删除失败')
        }
      } catch (error) {
        console.error('删除失败', error)
        ElMessage.error('删除失败')
      }
    })
    .catch(() => {})
}

// 重置表单
const resetForm = () => {
  if (permissionFormRef.value) {
    permissionFormRef.value.resetFields()
  }
  permissionForm.id = null
  permissionForm.permissionName = ''
  permissionForm.permissionCode = ''
  permissionForm.permissionType = 1
  permissionForm.parentId = 0
  permissionForm.path = ''
  permissionForm.component = ''
  permissionForm.icon = ''
  permissionForm.sort = 0
  permissionForm.status = 1
}

// 提交表单
const submitForm = async () => {
  await permissionFormRef.value.validate(async (valid) => {
    if (valid) {
      try {
        let res
        if (dialogStatus.value === 'create') {
          res = await addPermission(permissionForm)
        } else {
          res = await updatePermission(permissionForm)
        }

        if (res.data.code === 1) {
          ElMessage.success(
            dialogStatus.value === 'create' ? '新增成功' : '更新成功'
          )
          dialogVisible.value = false
          fetchPermissionTree()
        } else {
          ElMessage.error(
            res.data.msg ||
              (dialogStatus.value === 'create' ? '新增失败' : '更新失败')
          )
        }
      } catch (error) {
        console.error(
          dialogStatus.value === 'create' ? '新增失败' : '更新失败',
          error
        )
        ElMessage.error(
          dialogStatus.value === 'create' ? '新增失败' : '更新失败'
        )
      }
    }
  })
}

// 初始化
onMounted(() => {
  fetchPermissionTree()
})
</script>

<style lang="scss" scoped>
.permission-container {
  padding: 20px;
}

.filter-container {
  margin-bottom: 20px;
}

.permission-tree-card {
  margin-bottom: 20px;
  border-radius: 8px;
  border-color: #3c9474;
}

.tree-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 10px;

  .header-left {
    display: flex;
    align-items: center;

    h3 {
      color: var(--primary-dark);
      margin: 0;
      font-size: 18px;
    }

    .permission-count {
      margin-left: 10px;
    }
  }

  .header-right {
    display: flex;
    align-items: center;

    .tree-legend {
      display: flex;
      margin-right: 15px;

      .legend-item {
        margin-left: 10px;
      }
    }
  }
}

.tree-table-header {
  display: flex;
  padding: 12px 8px;
  border-bottom: 1px solid #ebeef5;
  font-weight: bold;
  color: var(--primary-dark);
  background-color: var(--primary-light);
  border-radius: 4px;
  margin-bottom: 10px;

  .table-header-item {
    padding: 0 8px;
    text-align: left;

    &.table-header-name {
      flex: 3;
    }

    &.table-header-type,
    &.table-header-code {
      flex: 2;
    }

    &.table-header-action {
      flex: 3;
      text-align: right;
    }
  }
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  padding: 10px 8px;
  transition: background-color 0.3s;
  border-radius: 4px;

  &:hover {
    background-color: #f0f7f4;
  }

  .node-id {
    width: 50px;
    color: var(--el-text-color-secondary);
    font-size: 13px;
  }

  .node-label {
    flex: 3;
    display: flex;
    align-items: center;

    .el-icon {
      margin-right: 5px;
      color: var(--primary-color);
    }

    span {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }

  .node-type {
    flex: 2;
  }

  .node-code {
    flex: 2;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .node-actions {
    flex: 3;
    display: flex;
    justify-content: flex-end;
    gap: 5px;

    .action-button {
      padding: 5px 10px;
      font-size: 13px;
      font-weight: 500;
      border-radius: 4px;

      &.el-button--primary {
        border-color: var(--primary-color);
        background-color: rgba(60, 148, 116, 0.1);
        color: var(--primary-dark);

        &:hover,
        &:focus {
          border-color: var(--primary-dark);
          background-color: rgba(60, 148, 116, 0.2);
          color: var(--primary-dark);
        }
      }

      &.el-button--danger {
        border-color: var(--danger-color);
        background-color: rgba(245, 108, 108, 0.1);
        color: var(--danger-color);

        &:hover,
        &:focus {
          border-color: #f56c6c;
          background-color: rgba(245, 108, 108, 0.2);
          color: var(--danger-color);
        }
      }

      .el-icon {
        margin-right: 4px;
      }
    }
  }
}

.icon-selector {
  display: flex;
  flex-wrap: wrap;
  max-height: 300px;
  overflow-y: auto;
}

.icon-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  margin: 5px;
  cursor: pointer;
  border-radius: 4px;
  transition: background-color 0.3s;
}

.icon-item:hover {
  background-color: #f0f7f4;
}

.icon-item .el-icon {
  font-size: 24px;
  margin-bottom: 5px;
  color: #2c5e43;
}

.icon-item span {
  font-size: 12px;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  width: 100%;
  text-align: center;
}

.form-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

:deep(.el-tree-node__content) {
  padding: 10px 0;
  border-bottom: 1px solid #f0f0f0;
}

:deep(.el-tree-node__children .el-tree-node__content) {
  padding-left: 20px;
}

:deep(.el-button--primary.is-link) {
  &:hover,
  &:focus {
    color: var(--primary-dark);
    text-decoration: none;
  }
}

:deep(.el-button--danger.is-link) {
  &:hover,
  &:focus {
    color: #f56c6c;
    text-decoration: none;
  }
}

:deep(.el-tag--success) {
  background-color: #e6f3ed;
  border-color: #3c9474;
  color: #2c5e43;
}

:deep(.el-tag--warning) {
  background-color: #fdf6ec;
  border-color: #e6a23c;
  color: #b88230;
}

:deep(.el-tag--info) {
  background-color: #f4f4f5;
  border-color: #909399;
  color: #606266;
}
</style>
